package cn.com.egova.erp.realm;

import cn.com.egova.erp.biz.IEmpBiz;
import cn.com.egova.erp.entity.Emp;
import cn.com.egova.erp.entity.Menu;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.List;

/**
 * Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”
 * Created by yuanchao on 2020/6/15.
 */
public class ErpRealm extends AuthorizingRealm {
    private IEmpBiz empBiz;

    public void setEmpBiz(IEmpBiz empBiz) {
        this.empBiz = empBiz;
    }

    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //获取当前登录用户的菜单
        Emp emp = (Emp) principalCollection.getPrimaryPrincipal();
        List<Menu> menus = empBiz.getMenusByEmpUuid(emp.getUuid());
        //加入授权
        for (Menu m : menus) {
            //这里采用menuname来做授权的key值，那么在配置信息里也要与之对应(url=perms[菜单名称])
            info.addStringPermission(m.getMenuname());
        }
        return info;
    }

    /**
     * 认证
     *
     * @param authenticationToken
     * @return 返回null表示失败，返回AuthenticationInfo的实现类表示认证成功
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //通过令牌得到用户名、密码
        UsernamePasswordToken upt = (UsernamePasswordToken) authenticationToken;
        String pwd = new String(upt.getPassword());
        //调用登录查询
        Emp loginUser = empBiz.findByUsernameAndPwd(upt.getUsername(), pwd);
        //认证成功
        if (loginUser != null) {
            //参数1： 主角=登陆用户
            //参数2：授权码：密码
            //参数3：realm的名称
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(loginUser, pwd, getName());
            return info;
        }
        return null;
    }
}
